﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebHoiChoMuaBan.Models;
using WebHoiChoMuaBan.Controllers.Global;

namespace WebHoiChoMuaBan.Controllers.Helpers
{
    public class NewsHelper : HelperBase
    {
        public struct NewsResult
        {
            public int id;
            public string title;
            public string intro;
            public int viewCount;
            public string imgThumb;
            public bool state;
            public Member member;
            public DateTime pubDate;
            public int like;
        }

        public struct FetchNewsResult
        {
            public List<News> news;
            public int totalPages;
        }

        private int memberId;
        private MemberHelper memberHelper;
        private News news;

        public int MemberId
        {
            get { return memberId; }
            set { memberId = value; }
        }

        public NewsHelper()
            : base()
        {
            this.memberId = 0;
            this.memberHelper = null;
        }

        public NewsHelper(int memberId)
            : base()
        {
            this.memberId = memberId;
            this.memberHelper = null;
        }

        public NewsHelper(MemberHelper hMem)
            : base()
        {
            this.memberHelper = hMem;
        }

        public News getNews(int id)
        {
            this.news = this.dataContext.News.SingleOrDefault(n => n.NewsId == id);

            if (this.news != null)
                this.news.IsEdit = true;
            return this.news;
        }

        /// <summary>
        /// Lấy số tin theo tham số và theo loại tin của user
        /// </summary>
        /// <param name="newsTypeId"></param>
        /// <param name="numOfNews"></param>
        /// <returns></returns>
        public List<News> GetNewsByNewsTypeId(int newsId, int numOfNews)
        {
            if (numOfNews < 0)
            {
                News curNews = this.getNews(newsId);
                if (curNews != null)
                {
                    var news = (from n in this.dataContext.News
                                where n.NewsTypeId == curNews.NewsTypeId && n.MemId == this.memberId
                                orderby n.NewsDate descending
                                select n).Take(numOfNews);
                    return news.ToList();
                }
            }
            else
            {
                News curNews = this.getNews(newsId);
                if (curNews != null)
                {
                    var news = (from n in this.dataContext.News
                                where n.NewsTypeId == curNews.NewsTypeId && n.MemId == this.memberId
                                orderby n.NewsDate descending
                                select n).Take(numOfNews);
                    return news.ToList();
                }
            }
            return null;
        }

        public List<News> GetOtherNews(int? uid, int numOfNewsPerPage)
        {
            var news = (from n in this.dataContext.News
                        where n.MemId == uid.Value
                        orderby n.NewsDate descending
                        select n).Take(numOfNewsPerPage);
            return news.ToList();
        }

        //public List<News> GetNewsByNewsTypeIdOfAllUser(int newsTypeId)
        //{
        //    var news = (from n in this.dataContext.News
        //                where n.NewsTypeId == newsTypeId
        //                select n);
        //    return news.ToList();
        //}

        public double CountPage(List<News> lstNews)
        {
            double numberOfNews = (from n in this.dataContext.News
                                   select n).Count();
            return Math.Ceiling((double)lstNews.Count / Config.ITEMS_PER_ADMINPAGE);
        }

        //public List<News> PaggingNews(int index, List<News> lstNews)
        //{
        //    int numOfRecord = (index - 1) * Config.ITEMS_PER_ADMINPAGE;
        //    return lstNews.Skip(numOfRecord).Take(Config.ITEMS_PER_ADMINPAGE).ToList();
        //}

        public List<News> getNewNews(int page, int rowPerPage)
        {
            IEnumerable<NewsResult> newNews = null;
            if (this.memberHelper == null)
            {
                if (this.memberId > 0) // Lấy tin tức mới do một thành viên nào đó đăng
                {
                    newNews = from m in this.dataContext.Members
                              join n in this.dataContext.News
                              on m.MemId equals n.MemId
                              where m.MemId == this.memberId
                              orderby n.NewsDate descending
                              select new WebHoiChoMuaBan.Controllers.Helpers.NewsHelper.NewsResult
                              {
                                  id = n.NewsId,
                                  title = n.NewsTitle,
                                  intro = n.NewsIntro,
                                  viewCount = n.NewsViewCount,
                                  imgThumb = n.NewsThumb,
                                  pubDate = n.NewsDate

                              };
                }
                else //Lấy tin tức mới nhất của mọi người
                {
                    newNews = from n in this.dataContext.News
                              orderby n.NewsDate descending
                              select new WebHoiChoMuaBan.Controllers.Helpers.NewsHelper.NewsResult
                              {
                                  id = n.NewsId,
                                  title = n.NewsTitle,
                                  intro = n.NewsIntro,
                                  viewCount = n.NewsViewCount,
                                  imgThumb = n.NewsThumb,
                                  pubDate = n.NewsDate

                              };
                }
            }
            else //Lấy tin tức từ một đối tượng đã load sẵn
            {
                newNews = from n in this.memberHelper.Member.News
                          orderby n.NewsDate descending
                          select new WebHoiChoMuaBan.Controllers.Helpers.NewsHelper.NewsResult
                          {
                              id = n.NewsId,
                              title = n.NewsTitle,
                              intro = n.NewsIntro,
                              viewCount = n.NewsViewCount,
                              imgThumb = n.NewsThumb,
                              pubDate = n.NewsDate

                          };
            }

            return CreateListNews(page, rowPerPage, newNews);
        }

        public News GetNewsById(int newsId)
        {
            return this.dataContext.News.SingleOrDefault(m => m.NewsId == newsId);
        }

        public News myGetNewsById(int newsId)
        {
            return (from e in this.dataContext.News where e.NewsId==newsId select e).SingleOrDefault();
        }

        private List<News> CreateListNews(int page, int rowPerPage, IEnumerable<NewsResult> newNews)
        {
            List<NewsResult> pagedNewMemers = newNews.Skip((page - 1) * rowPerPage).Take(rowPerPage).ToList();

            int totalPages = (int)Math.Ceiling((double)newNews.Count() / rowPerPage);

            List<News> lstNews = new List<News>(totalPages);
            News news;
            foreach (var i in pagedNewMemers)
            {
                news = new News();
                news.NewsId = i.id;
                news.NewsTitle = i.title;
                news.NewsIntro = i.intro;
                news.NewsViewCount = i.viewCount;
                news.NewsThumb = i.imgThumb;
                news.NewsDate = i.pubDate;
                news.MemId = this.memberId;
                news.NewsLike = i.like;
                lstNews.Add(news);
            }
            return lstNews;
        }

        ////////////////////////////////////////////
        ////////////////////////////////////////////
        private FetchNewsResult CreateFetchNews(int page, int rowPerPage, IEnumerable<NewsResult> newNews)
        {
            List<NewsResult> pagedNewMemers = newNews.Skip((page - 1) * rowPerPage).Take(rowPerPage).ToList();

            int totalPages = (int)Math.Ceiling((double)newNews.Count() / rowPerPage);


            List<News> lstNews = new List<News>(totalPages);
            News news;
            foreach (var i in pagedNewMemers)
            {
                news = new News();
                news.NewsId = i.id;
                news.NewsTitle = i.title;
                news.NewsIntro = i.intro;
                news.NewsViewCount = i.viewCount;
                news.NewsDate = i.pubDate;
                news.NewsState = i.state;
                news.NewsThumb = i.imgThumb;
                news.Member = i.member;
                news.NewsLike = i.like;
                lstNews.Add(news);
            }
            FetchNewsResult result;
            result.totalPages = totalPages;
            result.news = lstNews;
            return result;
        }

        private FetchNewsResult CreateFetchNews_Admin(int page, int rowPerPage, IEnumerable<NewsResult> newNews)
        {
            List<NewsResult> pagedNewMemers = newNews.Skip((page - 1) * rowPerPage).Take(rowPerPage).ToList();

            int totalPages = (int)Math.Ceiling((double)newNews.Count() / rowPerPage);

            List<News> lstNews = new List<News>(totalPages);
            News news;
            foreach (var i in pagedNewMemers)
            {
                news = new News();
                news.NewsId = i.id;
                news.NewsTitle = i.title;
                news.NewsIntro = i.intro;
                news.NewsViewCount = i.viewCount;
                news.NewsDate = i.pubDate;
                news.NewsState = i.state;
                news.NewsThumb = i.imgThumb;
                news.Member = i.member;
                news.MemId = this.memberId;
                news.NewsLike = i.like;
                lstNews.Add(news);
            }
            FetchNewsResult result;
            result.totalPages = totalPages;
            result.news = lstNews;
            return result;
        }

        public FetchNewsResult getListNews(int pageNum, int itemPerPage)
        {
            IEnumerable<NewsResult> news = null;
            if (this.memberId > 0) // Lấy tin tức mới do một thành viên nào đó đăng
            {
                news = from n in this.dataContext.News
                       where n.MemId == this.memberId && n.NewsState == true
                       orderby n.NewsId descending
                       select new NewsResult
                       {
                           id = n.NewsId,
                           title = n.NewsTitle,
                           intro = n.NewsIntro,
                           pubDate = n.NewsDate,
                           state = n.NewsState,
                           viewCount = n.NewsViewCount,
                           member = n.Member,
                           imgThumb = n.NewsThumb,
                           like = n.NewsLike,
                       };
            }
            return CreateFetchNews(pageNum, itemPerPage, news);
        }

        /// <summary>
        /// Dùng trong trang admin, load tất cả các tin tức theo thể loại của tất cả các user
        /// </summary>
        /// <param name="pageNum">Số trang hiện tại</param>
        /// <param name="itemPerPage">Số tin trên 1 trang</param>
        /// <returns></returns>
        public FetchNewsResult getListNews_Admin(int pageNum, int itemPerPage, int? newsTypeId)
        {
            IEnumerable<NewsResult> news = null;
            news = from n in this.dataContext.News
                   where n.NewsTypeId == newsTypeId
                   orderby n.NewsDate descending
                   select new NewsResult
                   {
                       id = n.NewsId,
                       title = n.NewsTitle,
                       intro = n.NewsIntro,
                       pubDate = n.NewsDate,
                       state = n.NewsState,
                       viewCount = n.NewsViewCount,
                       member = n.Member,
                       imgThumb = n.NewsThumb,
                       like = n.NewsLike,
                   };
            return CreateFetchNews(pageNum, itemPerPage, news);
        }

        //
        // Insert Methods
        public void Add(News news)
        {
            this.dataContext.News.InsertOnSubmit(news);
        }

        //Delete Methods
        public void Delete(News news)
        {
            this.dataContext.News.DeleteOnSubmit(news);
        }

        public bool AddComment(string content, int newsId, int memberId, int? comIdReply)
        {
            News news = GetNewsById(newsId);
            if (news != null)
            {
                NewsComment comment = new NewsComment();
                comment.ComDate = DateTime.Now;
                comment.ComContent = content;
                comment.MemIdSender = memberId;
                if (comIdReply != null)
                {

                    comment.ComIdReply = comIdReply.Value;
                }
                news.NewsComments.Add(comment);
                Save();
                return true;
            }
            return false;
        }

        public List<NewsComment> getListCommentByProductId(int pId)
        {
            List<NewsComment> result = (from e in this.dataContext.NewsComments where (e.NewsId == pId && e.ComIdReply == null) orderby e.ComDate descending select e).ToList<NewsComment>();
            return result;
        }
        public List<NewsComment> getListCommentReplyByCommentId(int cId)
        {
            List<NewsComment> result = (from e in this.dataContext.NewsComments where e.ComIdReply == cId orderby e.ComDate descending select e).ToList<NewsComment>();
            return result;
        }

        public bool SaveNews(News pro, string memId)
        {
            if (pro.NewsId.Equals("0"))
            {
                return true;
            }
            else
            {
                try
                {
                    News tmp = GetNewsById(int.Parse(pro.NewsId + ""));
                    tmp.NewsLike = pro.NewsLike;
                    Save();
                    MemberLikeNew mlike = new MemberLikeNew();
                    mlike.MemId = int.Parse(memId);
                    mlike.NProId = pro.NewsId;
                    this.dataContext.MemberLikeNews.InsertOnSubmit(mlike);
                    this.dataContext.SubmitChanges();
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
            }
        }

        //
        // Persistence
        public void Save()
        {
            this.dataContext.SubmitChanges();
        }
    }
}